package 蚂蚁课堂;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.IntStream;
import java.util.stream.LongStream;

/**
 * 基于数组的阻塞链表，插入和删除公用一把锁，降低性能。
 */
public class ArrayBlockingQueueDemo {


    /**
     * 创建给定大小的阻塞队列
     */
    private static ArrayBlockingQueue<Integer> arrayBlockingQueue1=new ArrayBlockingQueue(10);
    /**
     * 创建给定大小的阻塞队列和不指定访问策略
     */
    private static ArrayBlockingQueue arrayBlockingQueue2=new ArrayBlockingQueue(10,false);
    /**
     * 创建给定大小的阻塞队列和不指定访问策略，并且给定一个初始集合元素
     */
    private static ArrayBlockingQueue<Integer> arrayBlockingQueue3=new ArrayBlockingQueue(10,false, Arrays.asList(1,2,3));

    public static void t1() throws InterruptedException {
        for (int i=0;i<12;i++){
            Integer take = arrayBlockingQueue3.take();
            System.out.println(take);
        }

    }

    /**
     * add()方法：是向队列中插入元素，当队列有空间插入成功则返回true，若队列中没有空间还要插入的话就直接抛异常
     */
    public static void add(){
        for (int i=0;i<12;i++){
            boolean add = arrayBlockingQueue3.add(i);
            System.out.println(add);
        }
    }

    /**
     * 清空队列
     */
    public static void clear(){
        arrayBlockingQueue3.clear();
        System.out.println(arrayBlockingQueue3.size());
    }

    /**
     * 检索队列中是否包含指定的元素，有则返回true，没有则返回false
     */
    public static void contains(){
        boolean contains = arrayBlockingQueue3.contains(5);
        System.out.println(contains);
    }

    public static void drainTo() throws InterruptedException {
        arrayBlockingQueue3.put(9);
        List<Integer> objects = Arrays.asList();
        int i = arrayBlockingQueue3.drainTo(objects,2);
        System.out.println(i);
    }

    /**
     * offer()：若队列有空间则直接插入数据并返回true，若队列没有空间则直接返回false，并不会阻塞等待
     */
    public static void offer(){
        IntStream range = IntStream.range(1, 12);
        /**
         * true、true、true、true、true、true、true、true、false
         */
        range.forEach(x-> System.out.println(arrayBlockingQueue1.offer(x)));
    }

    /**
     * peek()：检索但不删除此队列的头，如果此队列为空，则返回 null 。
     */
    public static void peek(){
        Integer peek = arrayBlockingQueue3.peek();
        Integer peek1 = arrayBlockingQueue1.peek();
        System.out.println(peek);//1
        System.out.println(peek1);//null
        System.out.println(arrayBlockingQueue3.size());//3：长度还是3，则说明peek()只检索队列头部，不删除

    }

    /**
     * 检索并删除此队列的头，如果此队列为空，则返回 null ，他不向take()方法，若队列为空则阻塞等待
     */
    public static void poll(){
        Integer poll = arrayBlockingQueue1.poll();
        Integer poll1 = arrayBlockingQueue3.poll();
        System.out.println(poll);//null
        System.out.println(poll1);//1
    }

    /**
     * put()：在该队列的尾部插入指定的元素，如果队列已满，则等待空间变为可用【若空间满了则阻塞等待】
     * 阻塞了后面的代码就不会执行
     */
    public static void put(){
        IntStream range = IntStream.range(1, 12);
        range.forEach(x->{
            try {
                arrayBlockingQueue1.put(x);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        //
        System.out.println(arrayBlockingQueue1.size());
    }

    /**
     * remove()：删除指定的元素，若该元素存在则删除并返回true。若该元素不存在则返回false
     */
    public static void remove(){
        boolean remove = arrayBlockingQueue3.remove(1);
        boolean remove1 = arrayBlockingQueue3.remove(9);
        System.out.println(remove);//true
        System.out.println(remove1);//false
    }

    /**
     * take() 检索并删除此队列的头,若队列为空，则进入阻塞等待状态
     * 将删除的数据返回
     */
    public static void take(){
        LongStream.range(1,20).forEach(x-> {
            try {
                Integer take = arrayBlockingQueue3.take();
                System.out.println(take);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }
    public static void main(String[] args) throws InterruptedException {
        take();
    }
}
